<?php

namespace DB;

use Config\Base as Config;
use Facebook;
use Models\Profile;
use Models\User;

class UserService {

    /**
     * @param integer $profile_id
     * @return NULL|User
     */
    public function findByProfileId($profile_id) {
        $sql = 'SELECT u.* FROM `user` u
			JOIN `profile` p ON p.`user_id` = u.`id`
			WHERE p.`id` = :profile_id';

        $user = DAO::getInstance()->query($sql, array(
            'profile_id' => $profile_id
        ));

        if (count($user) == 0) {
            return null;
        }

        $user = new User($user[0]);
        $user = $this->getUserRoles($user);
        $user = $this->getUserProfile($user);
        return $user;
    }

    /**
     * @param User $user
     * @return User
     */
    public function getUserProfile(User $user) {
        $sql = 'SELECT * FROM `profile` p WHERE p.`user_id` = :user_id';
        $profile = DAO::getInstance()->query($sql, array(
            'user_id' => $user->getId()
        ));

        if (count($profile) > 0) {
            $profile = new Profile($profile[0]);
            $user->fromArray(array('profile' => $profile));
        }
        return $user;
    }

    /**
     * @param Profile $profile
     * @return Profile
     */
    public function createProfile(Profile &$profile) {
        $data = $profile->toArray();
        if (!$profile->getId()) {
            unset($data['id']);
        }

        $t = array();
        foreach (array_keys($data) as $k) {
            $t[$k] = ":$k";
        }

        $t['created'] = 'NOW()';
        $t['updated'] = 'NOW()';

        $sql = 'INSERT into `profile` ('
            . implode(', ', array_keys($t))
            . ') VALUES ('
            . implode(', ', array_values($t))
            . ')';

        DAO::getInstance()->exec($sql, $data);

        return $profile;
    }

    /**
     * @param User $user
     * @return User
     */
    public function createUser(User $user) {
        $data = $user->toArray();

        if (!$user->getId()) {
            unset($data['id']);
        }
        $t = array();
        foreach (array_keys($data) as $k) {
            $t[$k] = ":$k";
        }

        $t['created'] = 'NOW()';
        $t['updated'] = 'NOW()';

        $sql = 'INSERT into `user` ('
            . implode(', ', array_keys($t))
            . ') VALUES ('
            . implode(', ', array_values($t))
            . ')';

        DAO::getInstance()->exec($sql, $data);

        $user->fromArray(array(
            'id' => DAO::getInstance()->lastInsertId()
        ));

        $sql = 'INSERT INTO `user_role` (`user_id`, `role_id`) VALUES (:user_id, :role_id)';
        DAO::getInstance()->exec($sql, array(
            'user_id' => $user->getId(),
            'role_id' => $user::ROLE_GUEST
        ));

        return $user;
    }

    /**
     *
     * @param User $user
     */
    public function updateUser(User $user) {
        $data = $user->toArray();
        $t = array();
        foreach (array_keys($data) as $k) {
            $t[] = "`$k` = :$k";
        }

        $t[] = '`updated` = NOW()';

        $sql = 'UPDATE `user` SET '
            . implode(', ', $t)
            . ' WHERE id = :id';

        DAO::getInstance()->exec($sql, $data);
    }

    /**
     * @param Profile $profile
     */
    public function updateProfile(Profile $profile) {
        $data = $profile->toArray();
        $t = array();
        foreach (array_keys($data) as $k) {
            if ($k != 'id') {
                $t[] = "`$k` = :$k";
            }
        }

        $t[] = '`updated` = NOW()';

        $sql = 'UPDATE `profile` SET '
            . implode(', ', $t)
            . ' WHERE id = :id';

        DAO::getInstance()->exec($sql, $data);
    }

    /**
     * @param integer $id
     * @throws \Exception
     * @return User
     */
    public function getUser($id) {
        $sql = 'SELECT u.* FROM `user` u WHERE u.`id` = :id';

        $user = DAO::getInstance()->query($sql, array(
            'id' => $id
        ));

        $user = array_shift($user);
        if (!$user) {
            session_destroy();
            throw new \Exception("User with id: $id not found");
        }
        $user = new User($user);

        $this->getUserRoles($user);
        $this->getUserProfile($user);

        return $user;
    }

    /**
     * @param User $user
     * @return User
     */
    public function getUserRoles(User &$user) {
        $sql = 'SELECT * FROM `user_role` ur '
            . 'JOIN `role` r ON r.`id` = ur.`role_id` '
            . 'WHERE ur.`user_id` = :id';
        $roles = DAO::getInstance()->query($sql, array(
            'id' => $user->getId()
        ));

        $user->fromArray(array('roles' => $roles));

        return $user;
    }

    /**
     * @return User:
     */
    public function getUserList() {
        $sql = 'SELECT u.* FROM `user` u';
        $list = DAO::getInstance()->query($sql);

        foreach ($list as &$user) {
            $user = new User($user);
            $this->getUserRoles($user);
        }

        return $list;
    }
}